package com.threeox.commonlibrary.ui.view.engineview.multipagemodel;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.alibaba.fastjson.JSONObject;
import com.threeox.commonlibrary.R;
import com.threeox.commonlibrary.entity.engine.ReloadType;
import com.threeox.commonlibrary.entity.engine.event.FragmentMsg;
import com.threeox.commonlibrary.entity.engine.event.ViewMessage;
import com.threeox.commonlibrary.entity.engine.model.multipage.DynamicPageDataMessage;
import com.threeox.commonlibrary.entity.engine.model.multipage.MultiPageMessage;
import com.threeox.commonlibrary.entity.engine.model.multipage.NavigationDisplayPosition;
import com.threeox.commonlibrary.entity.engine.model.multipage.PageDataMessage;
import com.threeox.commonlibrary.entity.engine.request.base.BaseRequestMsg;
import com.threeox.commonlibrary.inter.OnRequestListener;
import com.threeox.commonlibrary.ui.fragment.base.BaseModelFragment;
import com.threeox.commonlibrary.ui.view.engineview.base.CommonModelView;
import com.threeox.commonlibrary.ui.view.inter.IPageDataView;
import com.threeox.commonlibrary.ui.view.inter.engine.base.IBaseExtend;
import com.threeox.commonlibrary.ui.view.inter.engine.multipage.IMultiPageExtend;
import com.threeox.commonlibrary.ui.view.inter.engine.multipage.INavigationIndicator;
import com.threeox.commonlibrary.ui.view.inter.engine.multipage.OnNavigationListener;
import com.threeox.commonlibrary.ui.view.multipagenavigation.CommonPageDataView;
import com.threeox.commonlibrary.util.request.RequestHelper;
import com.threeox.utillibrary.util.EmptyUtils;
import com.threeox.utillibrary.util.LogUtils;
import com.threeox.utillibrary.util.res.LayoutUtils;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @ClassName: MultiPageModelView
 * 
 * @Description: TODO(多页面模型View)
 * 
 * @author 赵屈犇
 * 
 * @date 创建时间: 2017/8/10 13:43
 * 
 * @version 1.0
 * 
 */
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class MultiPageModelView extends CommonModelView implements ViewPager.OnPageChangeListener, OnNavigationListener, OnRequestListener {

    private FragmentManager mFragmentManager;

    private MyPagerAdapter mAdapter;
    // 页面布局 包裹 Fragment
    private ViewGroup mContentViewGroup;
    // 多页面模型的布局
    private LinearLayout mMultiPageModelLayout;
    // 导航器
    private INavigationIndicator mNavigationIndicator;

    private List<View> mViews;// 内容view集合
    private List<Fragment> mFragments;// Fragmet 的集合
    private MultiPageMessage mMultiPageMessage;
    private List<PageDataMessage> mPageDataMessages;
    private List<IPageDataView> mPageDataViews = new ArrayList<IPageDataView>();// 子View集合
    private List<DynamicPageDataMessage> dynamicPageDataMessages = new ArrayList<DynamicPageDataMessage>();// 子View数据集合 动态渲染
    private View[] dynamicPageViews = null;// 动态渲染子view集合

    private int mCurrentIndex = 0;// 当前显示的Fragment 页面的Index
    private int mContentLayoutId = R.id.id_multipagemodel_content_layout;// 内容布局Id

    protected RequestHelper mRequestHelper;// 请求帮助类
    protected BaseRequestMsg mBaseRequestMsg;// 请求对象

    protected IMultiPageExtend mMultiPageExtend;

    public MultiPageModelView(Context context) {
        this(context, null);
    }

    public MultiPageModelView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MultiPageModelView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void initView() {
        super.initView();
        LayoutUtils.inflate(mContext, R.layout.view_multipage_model, this);
        mContainerLayout = findViewById(R.id.id_multipagemodel_container);
        mMultiPageModelLayout = findViewById(R.id.id_multipagemodel_layout);
    }

    @Override
    public void initData(Intent intent) {
        super.initData(intent);
        try {
            if (!(mContext instanceof FragmentActivity)) {
                LogUtils.e(TAG, "使用多页面模型的Activity必须继承于" + FragmentActivity.class.getSimpleName());
                return;
            } else {
                this.mFragmentManager = ((FragmentActivity) mContext).getSupportFragmentManager();
            }
            if (mMultiPageMessage != null) {
                setBaseModelMsg(mMultiPageMessage);
                fillInView();
                initPublic();
                initCommonView();
                initExtend();
                initRequestMsg();
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "initData报错了:" + e.getMessage());
        }
    }

    @Override
    public MultiPageMessage initModelMessage(int fileName) {
        if (mMultiPageMessage == null) {
            if (mFileName == -1) {
                LogUtils.e(TAG, "给我一个模型文件吧!");
                return mMultiPageMessage;
            }
            this.mMultiPageMessage = mCommonConfig.getMultiPageMessage(mFileName);
        }
        return mMultiPageMessage;
    }

    @Override
    protected void initExtend() {
        try {
            if (mBaseExtend != null && mBaseExtend instanceof IMultiPageExtend) {
                this.mMultiPageExtend = (IMultiPageExtend) mBaseExtend;
                if (mMultiPageExtend != null) {
                    mMultiPageExtend.init(mContext, this);
                }
            }
        } catch (Exception e) {
            LogUtils.e(TAG, e.getMessage());
        }

    }

    /**
     * 初始化View
     *
     * @throws Exception
     */
    private void fillInView() throws Exception {
        initContents();
        initContentView();// 初始化内容区域
        initNavigationView();// 初始化导航View
    }

    @Override
    protected void initRequestMsg() {
        super.initRequestMsg();
        this.mRequestHelper = RequestHelper.newInstance();
        this.mRequestHelper.setIntent(mIntent);
        this.mBaseRequestMsg = mMultiPageMessage.getBaseRequestMsg();
        mRequestHelper.setOnRequestListener(this);
        execRequest();
    }

    /**
     * 执行请求
     */
    public void execRequest() {
        if (mBaseRequestMsg != null && mMultiPageMessage.isExecute()) {
            requestIn();
            mMultiPageModelLayout.setVisibility(View.GONE);
            mRequestHelper.execRequest(mBaseRequestMsg);
        }
    }

    /**
     * 初始化所有的内容集合
     */
    private void initContents() {
        if (null == mViews) {
            mViews = new ArrayList<View>();
        }
        if (null == mFragments) {
            mFragments = new ArrayList<Fragment>();
        }
        mPageDataMessages = mMultiPageMessage.getPageDataMessages();
        if (EmptyUtils.isNotEmpty(mPageDataMessages)) {
            for (PageDataMessage pageDataMessage: mPageDataMessages) {
                ViewMessage viewMessage = pageDataMessage.getViewMessage();
                if (viewMessage == null) {
                    FragmentMsg fragment = pageDataMessage.getFragment();
                    fragment.initParam(mIntent);
                    mFragments.add(fragment.start());
                } else {
                    viewMessage.initParam(mIntent);
                    mViews.add(viewMessage.initView(mContext));
                }
            }
        }
    }

    /**
     * 初始化内容区域
     * 
     * @throws Exception
     */
    private void initContentView() throws Exception {
        Constructor constructor = mMultiPageMessage.getContentViewClass().getConstructor(Context.class);
        mContentViewGroup = (ViewGroup) constructor.newInstance(mContext);
        mContentViewGroup.setId(mContentLayoutId);
        if (mContentViewGroup instanceof ViewPager) {
            if (EmptyUtils.isNotEmpty(mFragments)) {
                ((ViewPager) mContentViewGroup).setAdapter(new MyFragmentAdapter(mFragmentManager));
                ((ViewPager) mContentViewGroup).setOffscreenPageLimit(mFragments.size());
            } else {
                mAdapter = new MyPagerAdapter();
                ((ViewPager) mContentViewGroup).setAdapter(mAdapter);
                if (EmptyUtils.isNotEmpty(mViews)) {
                    ((ViewPager) mContentViewGroup).setOffscreenPageLimit(mViews.size());
                }
            }
            ((ViewPager) mContentViewGroup).setOnPageChangeListener(this);
        } else {
            try {
                FragmentTransaction transaction = mFragmentManager.beginTransaction();
                List<Fragment> fragments = mFragmentManager.getFragments();
                if (EmptyUtils.isNotEmpty(fragments)) {//
                    for (Fragment fragment : fragments) {
                        transaction.remove(fragment);
                    }
                    transaction.commit();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            FragmentTransaction transaction = mFragmentManager.beginTransaction();
            for (int i = 0; i < mFragments.size(); i++) {
                Fragment fragment = mFragments.get(i);
                transaction.add(mContentLayoutId, fragment);
                if (i == 0) {
                    transaction.show(fragment);
                } else {
                    transaction.hide(fragment);
                }
            }
            transaction.commit();
        }
        mMultiPageModelLayout.addView(mContentViewGroup);
    }

    /**
     * 初始化导航指示器
     *
     * @throws Exception
     */
    private void initNavigationView() throws Exception {
        Class navigationViewClass = mMultiPageMessage.getNavigationViewClass();
        if (navigationViewClass == null) {
            return;
        }
        Constructor constructor = navigationViewClass.getConstructor(Context.class);
        mNavigationIndicator = (INavigationIndicator) constructor.newInstance(mContext);
        if (mPageDataMessages != null) {
            mNavigationIndicator.setPageDataMessages(mPageDataMessages);
        }
        NavigationDisplayPosition displayPosition = mMultiPageMessage.getDisplayPosition();
        if (NavigationDisplayPosition.TOP == displayPosition) {// 标题栏在上
            mMultiPageModelLayout.addView((View) mNavigationIndicator, 0);
        } else if (NavigationDisplayPosition.BOTTOM == displayPosition) {// 标题栏在下
            LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 0);
            params.weight = 1;
            mContentViewGroup.setLayoutParams(params);
            mMultiPageModelLayout.addView((View) mNavigationIndicator);
        }
        mNavigationIndicator.setOnNavigationListener(this);
        LayoutParams layoutParams = mLayoutParamsUtils.getLinearLayoutParams(LayoutParams.MATCH_PARENT, mMultiPageMessage.getNavigationHeight());
        ((View) mNavigationIndicator).setLayoutParams(layoutParams);
    }

    @Override
    protected boolean verify(JSONObject value) {
        return true;
    }

    @Override
    protected boolean onBackPressed() {
        boolean isBack = super.onBackPressed();
        if (EmptyUtils.isNotEmpty(mFragments)) {
            for (Fragment fragment : mFragments) {
                if (fragment != null && fragment instanceof BaseModelFragment) {
                    boolean fragBack = ((BaseModelFragment) fragment).onBackPressed();
                    if (!fragBack) {
                        isBack = fragBack;
                    }
                }
            }
        }
        return isBack;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (EmptyUtils.isNotEmpty(mFragments)) {
            for (Fragment fragment : mFragments) {
                fragment.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

    @Override
    public void onClick(View v, ReloadType reloadType) {
        super.onClick(v, reloadType);
        execRequest();
    }

    /*================ViewPager的滑动事件====================*/
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        try {
            if (mNavigationIndicator != null) {
                mNavigationIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
            if (mMultiPageExtend != null) {
                mMultiPageExtend.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "onPageScrolled:" + e.getMessage());
        }
    }

    @Override
    public void onPageSelected(int position) {
        this.mCurrentIndex = position;
        if (mMultiPageExtend != null) {
            mMultiPageExtend.onPageSelected(position);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (mMultiPageExtend != null) {
            mMultiPageExtend.onPageScrollStateChanged(state);
        }
    }
    /*================ViewPager的滑动事件====================*/


    /*================导航指示器的响应事件====================*/
    @Override
    public void onNavigationClick(int position) {
        switchoverFragment(position);
    }

    @Override
    public void onNavigationDoubleClick(int position) {
        switchoverFragment(position);
    }

    /**
     * 切换Fragment
     *
     * @param position
     */
    public void switchoverFragment(int position) {
        try {
            if (mNavigationIndicator != null) {
                mNavigationIndicator.onPageScrolled(position, 0f, 0);
            }
            if (mContentViewGroup instanceof ViewPager) {
                ((ViewPager) mContentViewGroup).setCurrentItem(position);
            } else {
                if (mCurrentIndex != position) {
                    FragmentTransaction transaction = mFragmentManager.beginTransaction();
                    transaction.hide(mFragments.get(mCurrentIndex));
                    Fragment fragment = mFragments.get(position);
                    if (!fragment.isAdded()) {
                        transaction.add(mContentLayoutId, fragment);
                    }
                    transaction.show(fragment).commit();
                    this.mCurrentIndex = position;
                }
            }
            if (mMultiPageExtend != null) {
                mMultiPageExtend.switchoverFragment(position);
            }
        } catch (Exception e) {
            LogUtils.e(TAG, "switchoverFragment:报错了:" + e.getMessage());
        }
    }

    /*================导航指示器的响应事件====================*/


    public MultiPageMessage getMultiPageMessage() {
        return mMultiPageMessage;
    }

    public INavigationIndicator getNavigationIndicator() {
        return mNavigationIndicator;
    }

    public ViewGroup getContentViewGroup() {
        return mContentViewGroup;
    }

    /*======================请求对象的回调==========================*/
    @Override
    public void onSuccess(BaseRequestMsg requestMsg, String url, int id, String msg, Object data) {
        if (requestMsg != null) {
            putRequestResult(requestMsg.getKey(), data);
        }
        if (EmptyUtils.isNotEmpty(data) && data instanceof List) {
            List results = (List) data;
            boolean isIntercept = true;
            if (null != mMultiPageExtend) {
                isIntercept = mMultiPageExtend.onBeforeRequestSuccess(requestMsg, url, id, msg, results);
            }
            if (!isIntercept) {
                return;
            }
            mPageDataMessages = new ArrayList<>();
            dynamicPageDataMessages = new ArrayList<>();
            dynamicPageViews = new View[results.size()];
            if (mContentViewGroup != null && mContentViewGroup instanceof ViewPager) {
                ((ViewPager) mContentViewGroup).setAdapter(null);
            }
            mAdapter = new MyPagerAdapter();
            for (Object result: results) {
                PageDataMessage message = new PageDataMessage();
                mPageDataMessages.add(message);
                DynamicPageDataMessage pageDataMessage = new DynamicPageDataMessage();
                pageDataMessage.setResult(result);
                Integer layoutId = null;
                if (mMultiPageExtend != null) {
                    layoutId = mMultiPageExtend.onBeforeSetLayout(mMultiPageMessage.getLayoutId(), result, pageDataMessage);
                }
                layoutId = (layoutId == null) ? mMultiPageMessage.getLayoutId() : layoutId;
                pageDataMessage.setLayoutId(layoutId);
                dynamicPageDataMessages.add(pageDataMessage);
            }
            if (mNavigationIndicator != null) {
                mNavigationIndicator.setPageDataMessages(mPageDataMessages);
            }
            if (mContentViewGroup != null && mContentViewGroup instanceof ViewPager) {
                ((ViewPager) mContentViewGroup).setAdapter(mAdapter);
                ((ViewPager) mContentViewGroup).setOffscreenPageLimit((mPageDataViews.size() > 3) ? 3 : mPageDataViews.size());
            }
            mAdapter.notifyDataSetChanged();
            requestSucceed(data);
            mMultiPageModelLayout.setVisibility(VISIBLE);
            if (null != mMultiPageExtend) {
                mMultiPageExtend.onAfterRequestSuccess(requestMsg, url, id, msg, results);
            }
        } else {
            notData("没有更多数据啦!");
        }
    }

    @Override
    public void onError(BaseRequestMsg requestMsg, String url, int id, Object code, String msg, Object data) {
        requestFault(data, msg);
    }

    @Override
    public void inProgress(BaseRequestMsg requestMsg, float progress, long total, int id, String url) {

    }
    /*======================请求对象的回调==========================*/

    public List<Fragment> getFragments() {
        return mFragments;
    }

    public List<View> getViews() {
        return mViews;
    }

    /**
     * ViewPager 使用的PagerAdapter
     */
    class MyPagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            if (EmptyUtils.isNotEmpty(mViews)) {
                return mViews.size();
            }
            return dynamicPageDataMessages.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public View instantiateItem(ViewGroup container, final int position) {
            View view = null;
            if (EmptyUtils.isNotEmpty(mViews)) {
                view = mViews.get(position);
            } else {
                try {
                    view = dynamicPageViews[position];
                    if (view == null) {
                        view = (View) initDynamicPageView(position);
                    }
                } catch (Exception e) {
                    view = (View) initDynamicPageView(position);
                }
                dynamicPageViews[position] = view;
            }
            container.addView(view);
            return view;
        }

        /**
         * 初始化
         *
         * @param position
         * @return
         */
        private IPageDataView initDynamicPageView(int position) {
            DynamicPageDataMessage pageDataMessage = dynamicPageDataMessages.get(position);
            IPageDataView pageDataView = new CommonPageDataView(mContext);
            Object result = pageDataMessage.getResult();
            Integer layoutId = pageDataMessage.getLayoutId();
            pageDataView.setLayout(pageDataMessage.getLayoutId(), pageDataMessage.getResult());
            if (mMultiPageExtend != null) {
                mMultiPageExtend.onAfterSetLayout(layoutId, result, pageDataView, position);
            }
            return pageDataView;
        }

    }

    /**
     * ViewPager 使用的FragmentAdapter
     */
    class MyFragmentAdapter extends FragmentPagerAdapter {

        public MyFragmentAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
    }

    public int getCurrentIndex() {
        return mCurrentIndex;
    }
}
